package net.pinnoocle.playcommon.utils;

import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import net.pinnoocle.playcommon.constant.Constant;
import net.pinnoocle.playcommon.constant.wxConstant;
import org.apache.commons.lang3.StringUtils;

import java.text.MessageFormat;
import java.util.HashMap;

/**
 * 小程序接口
 * @author ye
 * @Description
 * @create 2021-09-03 17:48
 */

@Slf4j
public class WechatUtils {

    /**
     * 小程序登录
     * @param appId
     * @param secret
     * @return
     */
    public static JSONObject wechatLogin(String appId,String secret,String code){
        // 组装请求的Url
        String authUrl = MessageFormat.format(Constant.APPLET_AUTH_URL, new String[]{appId,secret,code});
        String result = HttpRequest.get(authUrl)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .execute()
                .body();
        return JSON.parseObject(result);
    }

    /**
     * 第三方平台代登录
     * @param appId
     * @param code
     * @param componentVerifyTicket
     * @return
     */
    public static JSONObject wechatLoginThird(String appId,String code,String componentVerifyTicket){
        // 组装请求的Url
        String componentAppid = wxConstant.sAppid;
        String authUrl = MessageFormat.format(Constant.APPLET_AUTH_THIRD_URL, new String[]{appId,code,componentAppid,componentVerifyTicket});
        String result = HttpRequest.get(authUrl)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .execute()
                .body();
        return JSON.parseObject(result);
    }

    /**
     * 获取小程序的accessToken
     * @param appId
     * @param secret
     * @return
     */
    public static JSONObject getWechatAccessToken(String appId,String secret){
        String authUrl = MessageFormat.format(Constant.APPLET_ACCESS_TOKEN_URL, new String[]{appId, secret});
        String result = HttpRequest.get(authUrl)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .execute()
                .body();
        return JSON.parseObject(result);
    }

    /**
     * 获取第三方平台接口调用凭据
     * @param componentVerifyTicket
     * @return
     */
    public static JSONObject getComponentAccessToken(String componentVerifyTicket){
        String componentAppid = wxConstant.sAppid;
        String componentAppSecret = wxConstant.appSecret;
        String apiComponentToken = wxConstant.API_COMPONENT_TOKEN;
        HashMap<String, String> requestMap = new HashMap<>();
        requestMap.put("component_appid",componentAppid);
        requestMap.put("component_appsecret",componentAppSecret);
        requestMap.put("component_verify_ticket",componentVerifyTicket);
        String result = HttpRequest.post(apiComponentToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(JSONObject.toJSONString(requestMap))
                .execute()
                .body();
        return JSON.parseObject(result);
    }

    /**
     * 快速注册小程序
     * @param registerMap
     * @param componentAccessToken
     * @return
     */
    public static String fastRegisterWechat(HashMap<String, Object> registerMap, String componentAccessToken){
        String result = HttpRequest.post(wxConstant.FAST_REGISTER_WECHAT+componentAccessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(JSONObject.toJSONString(registerMap))
                .execute()
                .body();
        log.info("registerJson==={}",JSONObject.toJSONString(registerMap));
        JSONObject jsonObject = JSON.parseObject(result);
        int errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return "success";
        }
        return jsonObject.getString("errmsg");
    }

    /**
     * 开始推送服务
     * @return
     */
    public static JSONObject startPushTicket(){
        HashMap<String, String> requestMap = new HashMap<>();
        String componentAppid = wxConstant.sAppid;
        String componentAppSecret = wxConstant.appSecret;
        requestMap.put("component_appid",componentAppid);
        requestMap.put("component_secret",componentAppSecret);
        String result = HttpRequest.post("https://api.weixin.qq.com/cgi-bin/component/api_start_push_ticket")
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(JSONObject.toJSONString(requestMap))
                .execute()
                .body();
        return JSON.parseObject(result);
    }

    /**
     * 获取授权码
     * @param componentAccessToken
     * @param authorizationCode
     * @return
     */
    public static JSONObject getAuthToken(String componentAccessToken,String authorizationCode){
        HashMap<String, String> requestMap = new HashMap<>();
        requestMap.put("component_appid",wxConstant.sAppid);
        requestMap.put("authorization_code",authorizationCode);
        String result = HttpRequest.post(wxConstant.API_QUERY_AUTH+componentAccessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(JSONObject.toJSONString(requestMap))
                .execute()
                .body();
        log.info("getAuthTokenJson==={}",JSONObject.toJSONString(requestMap));
        JSONObject jsonObject = JSON.parseObject(result);
        int errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return jsonObject;
        }
        log.info("getAuthTokenObject==={}",JSONObject.toJSONString(jsonObject));
        return null;
    }

    /**
     * 发送客服消息
     * @param requestMap
     * @param accessToken
     * @return
     */
    public static String sendCustom(HashMap<String, String> requestMap, String accessToken){
        String result = HttpRequest.post(wxConstant.CUSTOM_SEND+accessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(JSONObject.toJSONString(requestMap))
                .execute()
                .body();
        log.info("sendCustomJSON==={}",JSONObject.toJSONString(requestMap));
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("sendCustomObject==={}",JSONObject.toJSONString(jsonObject));
        int errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return "success";
        }
        return jsonObject.getString("errmsg");
    }

    /**
     * 获取预授权码
     * @return
     */
    public static JSONObject getPreCode(String componentAccessToken){
        HashMap<String, String> requestMap = new HashMap<>();
        requestMap.put("component_appid",wxConstant.sAppid);
        String result = HttpRequest.post(wxConstant.PRE_CODE+componentAccessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(JSONObject.toJSONString(requestMap))
                .execute()
                .body();
        log.info("getPreCodeJson==={}",JSONObject.toJSONString(requestMap));
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("getPreCodeObject==={}",result);
        boolean success = jsonObject.containsKey("pre_auth_code");
        if(success){
            return jsonObject;
        }
        return null;
    }

    /**
     * 使用授权码获取授权信息
     * @param authCode
     * @param componentAccessToken
     * @return
     */
    public static JSONObject getAuthInfoByAuthCode(String authCode,String componentAccessToken){
        if(StringUtils.isBlank(authCode)){
            return null;
        }
        HashMap<String, String> requestMap = new HashMap<>();
        requestMap.put("component_appid",wxConstant.sAppid);
        requestMap.put("authorization_code",authCode);
        String result = HttpRequest.post(wxConstant.AUTH_INFO+componentAccessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(JSONObject.toJSONString(requestMap))
                .execute()
                .body();
        log.info("getAuthInfoByAuthCodeJson==={}",JSONObject.toJSONString(requestMap));
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("getAuthInfoByAuthCodeObject==={}",result);
        boolean success = jsonObject.containsKey("authorization_info");
        if(success){
            return jsonObject;
        }
        return null;
    }

    /**
     * 获取/刷新接口调用令牌
     * @param componentAccessToken
     * @return
     */
    public static JSONObject getAuthorizerToken(String componentAccessToken,String appid,String refreshToken){
        HashMap<String, String> requestMap = new HashMap<>();
        requestMap.put("component_appid",wxConstant.sAppid);
        requestMap.put("authorizer_appid",appid);
        requestMap.put("authorizer_refresh_token",refreshToken);
        String result = HttpRequest.post(wxConstant.GET_AUTHORIZER_TOKEN+componentAccessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(JSONObject.toJSONString(requestMap))
                .execute()
                .body();
        log.info("getAuthorizerTokenJson==={}",JSONObject.toJSONString(requestMap));
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("getAuthorizerTokenObject==={}",result);
        boolean keyExists = jsonObject.containsKey("authorizer_access_token");
        if(keyExists){
            return jsonObject;
        }
        return null;
    }

    /**
     * 获取草稿箱列表
     * @return
     */
    public static JSONObject getTemplatedRaftList(String componentAccessToken){
        String templateRafListUrl = wxConstant.GET_TEMPLATED_RAFT_LIST + componentAccessToken;
        String result = HttpRequest.get(templateRafListUrl)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .execute()
                .body();
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("getTemplatedRaftListObject===={}",JSONObject.toJSONString(jsonObject));
        Integer errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return jsonObject;
        }
        return null;
    }

    /**
     * 将指定的草稿添加到代码模板库
     * @param draftId
     * @return
     */
    public static String addToTemplate(Integer draftId,String componentAccessToken){
        HashMap<String, Object> requestMap = new HashMap<>();
        requestMap.put("draft_id",draftId);
        requestMap.put("template_type",1);
        String result = HttpRequest.post(wxConstant.ADD_TO_TEMPLATE+componentAccessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(JSONObject.toJSONString(requestMap))
                .execute()
                .body();
        log.info("addToTemplateJson==={}",JSONObject.toJSONString(requestMap));
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("addToTemplateObject==={}",result);
        int errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return "success";
        }
        return jsonObject.getString("errmsg");
    }

    /**
     * 获取代码模板列表
     * @return
     */
    public static JSONObject getTemplateList(String componentAccessToken){
        String getTemplateListUrl = wxConstant.TEMPLATE_LIST + componentAccessToken;
        String result = HttpRequest.get(getTemplateListUrl)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .execute()
                .body();
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("getTemplatedRaftListObject===={}",JSONObject.toJSONString(jsonObject));
        Integer errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return jsonObject;
        }
        return null;
    }

    /**
     * 上传代码
     * @param accessToken
     * @param paramsMap
     * @return
     */
    public static String commitCode(String accessToken,HashMap<String,String> paramsMap){
        String result = HttpRequest.post(wxConstant.COMMIT_CODE+accessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(JSONObject.toJSONString(paramsMap))
                .execute()
                .body();
        log.info("commitCodeJson==={}",JSONObject.toJSONString(paramsMap));
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("commitCodeObject==={}",result);
        int errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return "success";
        }
        return jsonObject.getString("errmsg");
    }

    /**
     * 提交审核
     * @param postJson
     * @param accessToken
     * @return
     */
    public static String submitAudit(String postJson,String accessToken){
        String result = HttpRequest.post(wxConstant.SUBMIT_AUDIT+accessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(postJson)
                .execute()
                .body();
        log.info("submitAuditJson==={}",postJson);
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("submitAuditJsonObject==={}",result);
        int errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return jsonObject.getString("auditid");
        }
        return "";
    }

    /**
     * 发布已审核
     * @param accessToken
     * @return
     */
    public static String releaseWx(String accessToken){
        String result = HttpRequest.post(wxConstant.release_wx+accessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body("{}")
                .execute()
                .body();
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("releaseWxObject==={}",result);
        int errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return "success";
        }
        return jsonObject.getString("errmsg");
    }

    /**
     * 获取已上传的代码的页面列表
     * @param accessToken
     * @return
     */
    public static JSONObject getWxPage(String accessToken){
        String getPageUrl = wxConstant.GET_PAGE + accessToken;
        String result = HttpRequest.get(getPageUrl)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .execute()
                .body();
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("getPageObject===={}",JSONObject.toJSONString(jsonObject));
        Integer errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return jsonObject;
        }
        return null;
    }

    /**
     * 获取审核时可填写的类目信息
     * @param accessToken
     * @return
     */
    public static JSONObject getCategory(String accessToken){
        String getCategoryUrl = wxConstant.GET_CATEGORY + accessToken;
        String result = HttpRequest.get(getCategoryUrl)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .execute()
                .body();
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("getCategoryObject===={}",JSONObject.toJSONString(jsonObject));
        Integer errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return jsonObject;
        }
        return null;
    }

    /**
     * 设置小程序头像
     * @param accessToken
     * @param mediaId
     * @return
     */
    public static String setHeadImage(String accessToken,String mediaId){
        HashMap<String, Object> requestMap = new HashMap<>();
        requestMap.put("head_img_media_id",mediaId);
        requestMap.put("x1","0");
        requestMap.put("y1","0");
        requestMap.put("x2","0.99");
        requestMap.put("y2","0.99");
        String result = HttpRequest.post(wxConstant.SET_HEAD_IMAGE+accessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(JSONObject.toJSONString(requestMap))
                .execute()
                .body();
        log.info("setHeadImageJson==={}",JSONObject.toJSONString(requestMap));
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("setHeadImageObject==={}",result);
        int errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return "success";
        }
        return jsonObject.getString("errmsg");
    }

    /**
     * 设置小程序昵称
     * @param accessToken
     * @param nickName
     * @return
     */
    public static String setNickName(String accessToken,String nickName,String mediaId){
        HashMap<String, Object> requestMap = new HashMap<>();
        requestMap.put("nick_name",nickName);
        if(StringUtils.isNotBlank(mediaId)){
            requestMap.put("license",mediaId);
        }
        String result = HttpRequest.post(wxConstant.SET_NICK_NAME+accessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(JSONObject.toJSONString(requestMap))
                .execute()
                .body();
        log.info("setNickNameJson==={}",JSONObject.toJSONString(requestMap));
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("setNickNameObject==={}",result);
        int errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return jsonObject.containsKey("audit_id") ? "check" : "success";
        }
        return jsonObject.getString("errmsg");
    }

    /**
     * 检测昵称是否命中关键词
     * @param accessToken
     * @param nickName
     * @return
     */
    public static JSONObject checkNickName(String accessToken,String nickName){
        HashMap<String, Object> requestMap = new HashMap<>();
        requestMap.put("nick_name",nickName);
        String result = HttpRequest.post(wxConstant.CHECK_NICK_NAME+accessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(JSONObject.toJSONString(requestMap))
                .execute()
                .body();
        log.info("checkNickNameJson==={}",JSONObject.toJSONString(requestMap));
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("checkNickNameObject==={}",result);
        return jsonObject;
    }

    /**
     * 设置小程序简介
     * @param accessToken
     * @param signature
     * @return
     */
    public static String setSignature(String accessToken,String signature){
        HashMap<String, Object> requestMap = new HashMap<>();
        requestMap.put("signature",signature);
        String result = HttpRequest.post(wxConstant.SET_SIGNATURE+accessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(JSONObject.toJSONString(requestMap))
                .execute()
                .body();
        log.info("setSignatureJson==={}",JSONObject.toJSONString(requestMap));
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("setSignatureObject==={}",result);
        int errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return "success";
        }
        return jsonObject.getString("errmsg");
    }

    /**
     * 添加类目，默认娱乐休闲
     * @param accessToken
     * @return
     */
    public static String addCategory(String accessToken){
        String requestJson = "{\n" +
                "  \"categories\": [\n" +
                "    {\n" +
                "      \"first\": 150,\n" +
                "      \"second\": 666\n" +
                "    }\n" +
                "  ]\n" +
                "}";
        String result = HttpRequest.post(wxConstant.ADD_CATEGORY+accessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(requestJson)
                .execute()
                .body();
        log.info("addCategoryJson==={}",requestJson);
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("addCategoryObject==={}",result);
        int errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return "success";
        }
        return jsonObject.getString("errmsg");
    }

    /**
     * 配置小程序用户隐私保护指引
     * @param accessToken
     * @param requestJson
     * @return
     */
    public static String setPrivacySetting(String accessToken,String requestJson){
        String result = HttpRequest.post(wxConstant.SET_PRIVACY_SETTING+accessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(requestJson)
                .execute()
                .body();
        log.info("setPrivacySettingJson==={}",requestJson);
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("setPrivacySettingObject==={}",result);
        int errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return "success";
        }
        return jsonObject.getString("errmsg");
    }

    /**
     * 设置默认服务器域名
     * @param accessToken
     * @return
     */
    public static String addDefaultWxDomain(String accessToken){
        String requestJson = "{\n" +
                "  \"action\": \"add\",\n" +
                "  \"requestdomain\": [\"https://shop.julaike.vip\"],\n" +
                "  \"wsrequestdomain\": [\"wss://shop.julaike.vip\"],\n" +
                "  \"uploaddomain\": [\"https://shop.julaike.vip\"],\n" +
                "  \"downloaddomain\": [\"https://shop.julaike.vip\"],\n" +
                "  \"udpdomain\": [\"udp://shop.julaike.vip\"],\n" +
                "  \"tcpdomain\": [\"tcp://shop.julaike.vip\"]\n" +
                "}";
        String result = HttpRequest.post(wxConstant.DOMAIN_WX+accessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(requestJson)
                .execute()
                .body();
        log.info("addDefaultDomainJson==={}",requestJson);
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("addDefaultDomainObject==={}",result);
        int errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return "success";
        }
        return jsonObject.getString("errmsg");
    }

    /**
     * 设置默认业务域名
     * @param accessToken
     * @return
     */
    public static String addDefaultWebDomain(String accessToken){
        String requestJson = "{\n" +
                "  \"action\": \"add\",\n" +
                "  \"webviewdomain\": [\"https://shop.julaike.vip\"]\n" +
                "}";
        String result = HttpRequest.post(wxConstant.DOMAIN_WX+accessToken)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .body(requestJson)
                .execute()
                .body();
        log.info("addDefaultWebDomainJson==={}",requestJson);
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("addDefaultWebDomainObject==={}",result);
        int errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return "success";
        }
        return jsonObject.getString("errmsg");
    }

    /**
     * 获取小程序基本信息
     * @param accessToken
     * @return
     */
    public static JSONObject getBasicInfo(String accessToken){
        String getBasicInfo = wxConstant.GET_ACCOUNT_BASIC_INFO + accessToken;
        String result = HttpRequest.get(getBasicInfo)
                .header(Header.CONTENT_TYPE, "application/json")
                .setReadTimeout(10000)
                .setConnectionTimeout(5000)
                .execute()
                .body();
        JSONObject jsonObject = JSON.parseObject(result);
        log.info("getBasicInfoObject===={}",JSONObject.toJSONString(jsonObject));
        Integer errcode = jsonObject.getInteger("errcode");
        if(errcode == 0){
            return jsonObject;
        }
        return null;
    }
}
